package toolib.geom;

public class V3f {
	
	public static final V3f X = new V3f (1,0,0);
	public static final V3f Y = new V3f (0,1,0);
	
	public float x;
	public float y;
	public float z;
	
	
	public V3f () {
		x = 0;
		y = 0;
		z = 0;
	}
	
	public V3f (float theX, float theY) {
		x = theX;
		y = theY;
		z = 0;
	}
	
	public V3f (float theX, float theY, float theZ) {
		x = theX;
		y = theY;
		z = theZ;
	}

	public V3f (V2f theVector) {
		x = theVector.x;
		y = theVector.y;
		z = 0;
	}
	
	public final V3f abs () {
		if (x < 0) x *= -1;
		if (y < 0) y *= -1;
		if (z < 0) z *= -1;
		return this;
	}
	
	public final V3f add (float theX, float theY) {
		x += theX;
		y += theY;
		return this;
	}
	
	public final V3f add (float theX, float theY, float theZ) {
		x += theX;
		y += theY;
		z += theZ;
		return this;
	}
	
	public final V3f add (V2f theVector) {
		add (theVector.x, theVector.y);
		return this;
	}
	
	public final V3f add (V3f theVector) {
		add (theVector.x, theVector.y, theVector.z);
		return this;
	}
	
	public final V3f add (V3f[] theList) {
		for (V3f v : theList) {
			add (v);
		}
		return this;
	}
	
//	public final float distance (float theX, float theY) {
//		return (float) Math.sqrt (Math.pow (x - theX, 2) + Math.pow (y - theY, 2));
//	}
//	
//	public final float distance (V2f theVector) {
//		return distance (theVector.x, theVector.y);
//	}
//	
//	public static final float distance (float theAX, float theAY, float theBX, float theBY) {
//		return (float) Math.sqrt (Math.pow (theAX - theBX, 2) + Math.pow (theAY - theBY, 2));
//	}
//	
//	public static final float distance (V2f theA, V2f theB) {
//		return distance (theA.x, theA.y, theB.x, theB.y);
//	}
	
	public final V3f divide (float theDivisor) {
		x /= theDivisor;
		y /= theDivisor;
		z /= theDivisor;
		return this;
	}
	
	public final V3f divide (V3f theVector) {
		x /= theVector.x;
		y /= theVector.y;
		z /= theVector.z;
		return this;
	}
	
//	public final float dot (float theX, float theY) {
//		return x * theX + y * theY;
//	}
//	
//	public final float dot (V2f theVector) {
//		return x * theVector.x + y * theVector.y;
//	}

	public final boolean equals (float theX, float theY, float theZ) {
		return (x == theX && y == theY && z == theZ) ? true : false;
	}
	
	public final boolean equals (V3f theVector) {
		return equals (theVector.x , theVector.y, theVector.z);
	}
	
	public final V3f invert () {
		x *= -1;
		y *= -1;
		z *= -1;
		return this;
	}
	
	public final boolean isZero () {
		if (x == 0 && y == 0) {
			return true;
		}
		return false;
	}
	
	public final float length () {
		return (float) Math.sqrt (x * x + y * y);
	}
	
	public final float lengthSquared () {
		return (x * x + y * y);
	}
	
	public final V3f normalize () {
		float n = 1f / length ();
		x *= n;
		y *= n;
		z *= n;
		return this;
	}
	
	public static final V2f normalize (V2f theVector) {
		return theVector.clone ().normalize ();
	}
	
//	public final V2f rotate (float theRadian) {
//		float cos = (float) Math.cos (theRadian);
//		float sin = (float) Math.sin (theRadian);
//		x = cos * x - sin * y;
//		y = sin * x + cos * y;
//		return this;
//	}
	
	public final V3f scale (float theFactor) {
		x *= theFactor;
		y *= theFactor;
		z *= theFactor;
		return this;
	}

	public final V3f scale (V3f theVector) {
		x *= theVector.x;
		y *= theVector.y;
		z *= theVector.z;
		return this;
	}
	
	public static final V3f scale (V3f theVector, float theFactor) {
		return theVector.clone ().scale (theFactor);
	}
	
//	public static final V2f scale (V3f theVectorA, V3f theVectorB) {
//		return theVectorA.clone ().scale (theVectorB);
//	}
	
	public final V3f set (float theX, float theY) {
		x = theX;
		y = theY;
		return this;
	}
	
	public final V3f set (float theX, float theY, float theZ) {
		x = theX;
		y = theY;
		z = theZ;
		return this;
	}
	
	public final V3f set (V3f theVector) {
		x = theVector.x;
		y = theVector.y;
		z = theVector.z;
		return this;
	}
	
	public final V3f sub (float theX, float theY) {
		x -= theX;
		y -= theY;
		return this;
	}
	
	public final V3f sub (float theX, float theY, float theZ) {
		x -= theX;
		y -= theY;
		z -= theZ;
		return this;
	}
	
	public final V3f sub (V3f theVector) {
		sub (theVector.x, theVector.y, theVector.z);
		return this;
	}
	
	public final V3f sub (V3f[] theList) {
		for (V3f v : theList) {
			add (v);
		}
		return this;
	}
	
	public static final V3f sub (V3f theA, V3f theB) {
		return new V3f (theA.x - theB.x, theA.y - theB.y, theA.z - theB.z);
	}
	
	public static final V3f sum (V3f theA, V3f theB) {
		return new V3f (theA.x + theB.x, theA.y + theB.y, theA.z + theB.z);
	}
	
	public static final V3f sum (V3f[] theList) {
		V3f v = new V3f ();
		for (V3f o : theList) {
			v.add (o);
		}
		return v;
	}
	
	public String toString () {
		return "V3f [x:" + x + " y:" + y + " z:" + z + "]"; 
	}
	
	public V3f clone () {
		return new V3f (x, y, z);
	}
}